package com.vhall.component.service.subject.impl;

import cn.hutool.core.io.FileTypeUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vhall.component.dao.subject.SubjectMapper;
import com.vhall.component.dao.subject.SubjectRoomMapper;
import com.vhall.component.entity.room.vo.RoomInnerListVO;
import com.vhall.component.entity.room.vo.RoomsEntityVO;
import com.vhall.component.entity.subject.SubjectEntity;
import com.vhall.component.entity.subject.SubjectRoomEntity;
import com.vhall.component.entity.subject.vo.*;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.framework.common.utils.CollectionUtils;
import com.vhall.component.framework.common.utils.StringUtils;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.core.service.OssService;
import com.vhall.component.service.room.RoomInnerService;
import com.vhall.component.service.subject.SubjectConsoleService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 会议专题服务实现类
 *
 * @author jianyang
 */
@Service
public class SubjectConsoleServiceImpl implements SubjectConsoleService {

    @Autowired
    SubjectMapper subjectMapper;

    @Autowired
    SubjectRoomMapper subjectRoomMapper;

    @Autowired
    RoomInnerService roomInnerService;

    @Autowired
    OssService ossService;
    private static final String[] CHECK_TYPE = new String[]{"jpeg", "jpg", "png", "bmp"};
    @Override
    public Boolean create(CreateSubjectVo reqVo) {
        MultipartFile image = reqVo.getImage();
        checkFileType(image);
        String imageUrl = ossService.upload(image);
        SubjectEntity subjectEntity = new SubjectEntity();
        subjectEntity.setSubjectStatus(1);
        subjectEntity.setCreatedAt(LocalDateTime.now());
        subjectEntity.setIntroduction(reqVo.getIntroduction());
        subjectEntity.setCoverImage(imageUrl);
        subjectEntity.setAccountId(reqVo.getAccountId());
        subjectEntity.setName(reqVo.getName());
        subjectMapper.insert(subjectEntity);
        bindRoom(reqVo.getRoominfo(), subjectEntity.getId());
        return true;
    }

    private static void checkFileType(MultipartFile image) {
        try {
            String type = FileTypeUtil.getType(image.getInputStream());
            boolean contains = ArrayUtils.contains(CHECK_TYPE, type);
            if (!contains) {
                throw new BusinessException(BizErrorCode.BIZ_TYPE_NOT_ALLOWED);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Boolean update(UpdateSubjectVo reqVo) {
        SubjectEntity subjectEntity = checkSubjectStatus(reqVo.getSubjectId(), reqVo.getAccountId());
        //如果改变了图片
        if (reqVo.getChangeimg() == 1) {
            final String uploadImage = ossService.upload((MultipartFile) reqVo.getImage());
            subjectEntity.setCoverImage(uploadImage);
        }
        //如果改变了绑定的房间
        if (reqVo.getChangeRoom() == 1) {
            //先取消原来绑定的房间
            LambdaUpdateWrapper<SubjectRoomEntity> set = new LambdaUpdateWrapper<SubjectRoomEntity>().eq(SubjectRoomEntity::getSubjectId, reqVo.getSubjectId())
                    .set(SubjectRoomEntity::getBindStatus, 2).set(SubjectRoomEntity::getUpdatedAt, LocalDateTime.now());
            subjectRoomMapper.update(null, set);
            //再绑定新的房间
            String roominfo = reqVo.getRoominfo();
            bindRoom(roominfo, reqVo.getSubjectId());
        }
        subjectEntity.setUpdatedAt(LocalDateTime.now());
        subjectEntity.setIntroduction(reqVo.getIntroduction());
        subjectEntity.setName(reqVo.getName());
        subjectMapper.updateById(subjectEntity);
        return true;
    }

    @Override
    public Boolean del(SubjectIdsReqVo reqVo) {
        if (StringUtils.isNotEmpty(reqVo.getSubjectIds())) {
            final String[] split = reqVo.getSubjectIds().split(",");
            for (String subjectId : split) {
                SubjectEntity subjectEntity = checkSubjectStatus(Integer.parseInt(subjectId), reqVo.getAccountId());
                subjectEntity.setSubjectStatus(2);
                subjectEntity.setUpdatedAt(LocalDateTime.now());
                subjectMapper.updateById(subjectEntity);

                LambdaUpdateWrapper<SubjectRoomEntity> set = new LambdaUpdateWrapper<SubjectRoomEntity>().eq(SubjectRoomEntity::getSubjectId, Integer.parseInt(subjectId))
                        .set(SubjectRoomEntity::getBindStatus, 2).set(SubjectRoomEntity::getUpdatedAt, LocalDateTime.now());
                subjectRoomMapper.update(null, set);
            }
        }

        return true;
    }


    @Override
    public JSONObject list(SubjectListReqVo reqVo) {
        JSONObject jsonObject = new JSONObject();
        Page<SubjectEntity> page = new Page<>(reqVo.getPage(), reqVo.getPageSize());
        LambdaQueryWrapper<SubjectEntity> eq = new LambdaQueryWrapper<SubjectEntity>()
                .like(StringUtils.isNotEmpty(reqVo.getKeyword()), SubjectEntity::getName, reqVo.getKeyword())
                .eq(SubjectEntity::getSubjectStatus, 1)
                .eq(SubjectEntity::getAccountId, reqVo.getAccountId())
                .orderByDesc(SubjectEntity::getId);
        Page<SubjectEntity> subjectEntityPage = subjectMapper.selectPage(page, eq);

        List<SubjectEntity> records = subjectEntityPage.getRecords();
        ArrayList<JSONObject> jsonObjects = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(records)) {
            for (SubjectEntity record : records) {
                Integer id = record.getId();
                LambdaQueryWrapper<SubjectRoomEntity> set = new LambdaQueryWrapper<SubjectRoomEntity>()
                        .eq(SubjectRoomEntity::getSubjectId, id).eq(SubjectRoomEntity::getBindStatus, 1);
                Integer num = subjectRoomMapper.selectCount(set);
                JSONObject result = new JSONObject();
                result.put("num", num);
                result.put("created_at", record.getCreatedAt());
                result.put("id", record.getId());
                result.put("name", record.getName());
                jsonObjects.add(result);
            }
        }
        jsonObject.put("per_page", reqVo.getPageSize());
        jsonObject.put("total", subjectEntityPage.getTotal());
        jsonObject.put("page", subjectEntityPage.getCurrent());
        jsonObject.put("list", jsonObjects);
        return jsonObject;
    }

    /**
     * @param reqVo 请求参数
     * @return
     */
    @Override
    public JSONObject getInfo(SubjectBasicReqVo reqVo) {
        final SubjectEntity subjectEntity = checkSubjectStatus(reqVo.getSubjectId(), reqVo.getAccountId());
        JSONObject result = new JSONObject();
        result.put("cover_image", subjectEntity.getCoverImage());
        result.put("created_at", subjectEntity.getCreatedAt());
        result.put("introduction", subjectEntity.getIntroduction());
        result.put("name", subjectEntity.getName());
        List<SubjectRoomLandRespVo> subjectRoomLandRespVos = subjectRoomMapper.selectListBySubjectId(reqVo.getSubjectId());
        result.put("room_info", subjectRoomLandRespVos);
        return result;
    }

    /**
     * 获取可以关联的房间列表
     *
     * @param subjectRoomListReqVo
     * @return
     */
    @Override
    public JSONObject getRoomList(SubjectRoomListReqVo subjectRoomListReqVo) {
        if (subjectRoomListReqVo.getPageSize() == null) {
            subjectRoomListReqVo.setPageSize(10);
        }
        final RoomInnerListVO roomInnerListVO = new RoomInnerListVO();
        roomInnerListVO.setAccountId(subjectRoomListReqVo.getAccountId());
        roomInnerListVO.setKeyword(subjectRoomListReqVo.getKeyword());
        roomInnerListVO.setPage(subjectRoomListReqVo.getPage());
        roomInnerListVO.setPageSize(subjectRoomListReqVo.getPageSize());
        if (StringUtils.isNotEmpty(subjectRoomListReqVo.getRemRoomIds())) {
            roomInnerListVO.setExcludeRoomIds(subjectRoomListReqVo.getRemRoomIds());
        }
        final Page<RoomsEntityVO> roomsListByAccountId = roomInnerService.getRoomsListByAccountId(roomInnerListVO);
        final JSONObject object = new JSONObject();
        object.put("page", subjectRoomListReqVo.getPage());
        object.put("per_page", subjectRoomListReqVo.getPageSize());
        object.put("size", roomsListByAccountId.getTotal());
        object.put("list", roomsListByAccountId.getRecords());
        return object;
    }

    /**
     * 会议专题-绑定房间
     *
     * @param roomInfo
     * @param subjectId
     */
    public void bindRoom(String roomInfo, Integer subjectId) {
        JSONArray roominfos = JSONArray.parseArray(roomInfo);
        if (roominfos != null && roominfos.size() > 0) {
            for (Object roominfo : roominfos) {
                JSONObject jsonObject = JSONObject.parseObject(roominfo.toString());
                String room_id = jsonObject.getString("room_id");
                Integer sort = jsonObject.getInteger("sort");
                SubjectRoomEntity subjectRoomEntity = new SubjectRoomEntity();
                subjectRoomEntity.setSubjectId(subjectId);
                subjectRoomEntity.setCreatedAt(LocalDateTime.now());
                subjectRoomEntity.setRoomId(room_id);
                subjectRoomEntity.setSort(sort);
                subjectRoomEntity.setBindStatus(1);
                subjectRoomMapper.insert(subjectRoomEntity);
            }
        }
    }

    /**
     * 获取会议主题
     *
     * @param subjectId 主题id
     * @param accountId
     * @return
     */
    SubjectEntity checkSubjectStatus(Integer subjectId, Integer accountId) {
        LambdaQueryWrapper<SubjectEntity> eq = new LambdaQueryWrapper<SubjectEntity>().eq(SubjectEntity::getId, subjectId)
                .eq(SubjectEntity::getAccountId, accountId).eq(SubjectEntity::getSubjectStatus, 1);
        SubjectEntity subjectEntity = subjectMapper.selectOne(eq);
        if (subjectEntity == null) {
            throw new BusinessException(BizErrorCode.COMP_SUBJECT_NO_EXIST);
        }
        return subjectEntity;
    }
}
